package com.sunwayhorizo.health.business.clinic.emr.emrmanager;

import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;

import javax.ejb.Stateless;

import org.jboss.seam.Component;
import org.jboss.seam.annotations.Name;

import com.sunwayhorizo.health.business.base.BaseManager;
import com.sunwayhorizo.health.business.dto.ResultsDTO;
import com.sunwayhorizo.health.business.dto.clinic.emr.emrmanager.EmrManagerDTO;
import com.sunwayhorizo.health.business.patad.encounter.ReceivingManagerLocal;
import com.sunwayhorizo.health.common.DataTypeUtil;
import com.sunwayhorizo.health.common.DateUtil;
import com.sunwayhorizo.health.common.ListUtil;
import com.sunwayhorizo.health.common.StrUtil;
import com.sunwayhorizo.health.hl7.common.Hl7Exception;
import com.sunwayhorizo.health.hl7.datatypes.CS;
import com.sunwayhorizo.health.hl7.rim.ActParticipation;
import com.sunwayhorizo.health.hl7.rim.ControlAct;
import com.sunwayhorizo.health.hl7.rim.Document;
import com.sunwayhorizo.health.hl7.rim.PatientEncounter;
import com.sunwayhorizo.health.hl7.rim.Role;
import com.sunwayhorizo.health.hl7.vocabulary.ActCode;
import com.sunwayhorizo.health.hl7.vocabulary.ActMood;
import com.sunwayhorizo.health.hl7.vocabulary.ActRelationshipType;
import com.sunwayhorizo.health.hl7.vocabulary.ParticipationType;

/**
 * @ClassName EmrManager <br>
 * @PackageName com.sunwayhorizo.health.business.clinic.emr.emr <br>
 * @Description 电子病历管理 <br>
 * @Author jinzw <br>
 * @Date 2011-04-26 <br>
 * @Version 1.0 <br>
 * @ModifiedDesc <br>
 * @ModifiedDate <br>
 * @ModifiedBy <br>
 * @Email jinzw@sunwaysoft.com.cn <br>
 * @Copyright 2010-2020 horizo All Rights Reserved. <br>
 */
@Name("EmrManager")
@Stateless
public class EmrManager extends BaseManager implements EmrManagerLocal
{

    public Document newEmrManager(EmrManagerDTO dto) throws Hl7Exception
    {
        //创建病历管理动作
        Document document = this.getActFactory().newDocument(ActMood.EVN, ActCode.EMRMANAGER, null);
        
        //设置病历管理状态值
        converDocToDto(document, dto);
        
        //角色参与病历管理状态
        Map<CS,Role> socopeMap = findEmrManegerParticiRole(dto);
        constructParticipationList(socopeMap,dto);
        
        //创建controlAct
        ControlAct controlAct = newControlAct(document);
        
        //持久化
        save(controlAct);
        log.info("EmrManager-newEmrController：病历开启成功"+document.getActId());
        return document;
    }


    public Document newEmrManagerNotPersist(EmrManagerDTO dto) throws Hl7Exception
    {
        //创建病历管理动作
        Document document = this.getActFactory().newDocument(ActMood.EVN, ActCode.EMRMANAGER, null);
        
        //设置病历管理状态值
        converDocToDto(document, dto);
        
        //角色参与病历管理状态
        Map<CS,Role> socopeMap = findEmrManegerParticiRole(dto);
        constructParticipationList(socopeMap,dto);
        
        log.info("EmrManager-newEmrController：病历开启成功");
        return document;
    }


    public ResultsDTO medicalRecordSubmit(EmrManagerDTO dto) throws Hl7Exception
    {
        Document document = converDocument(dto);
        if (null != document)
        {
            em.merge(document);
        }
        return this.getResultsDTO("病历提交成功", true, "");
    }


    public ResultsDTO medicalRecordReturn(EmrManagerDTO dto) throws Hl7Exception
    {
        Document document = converDocument(dto);
        if (null != document)
        {
            update(document);
            ReceivingManagerLocal receivingManager = (ReceivingManagerLocal)Component.getInstance("ReceivingManager");
            receivingManager.returnLastRemove(dto.getPatientId(), document);
        }
        return this.getResultsDTO("病历打回成功", true, "");
    }


    public ResultsDTO medicalRecordComplete(EmrManagerDTO dto) throws Hl7Exception
    {

        Document document = converDocument(dto);
        if (null != document)
        {
            em.merge(document);
        }
        return this.getResultsDTO("病历审核通过", true, "");
    }


    public ResultsDTO medicalRecordClean(EmrManagerDTO dto) throws Hl7Exception
    {
        Document document = converDocument(dto);
        if (null != document)
        {
            update(document);
            //病历动作跟接诊动作绑定
            ReceivingManagerLocal receivingManager = (ReceivingManagerLocal)Component.getInstance("ReceivingManager");
            PatientEncounter patientEncounter = receivingManager.getNewReceiving(dto.getPatientId(), document);
            //当患者没有转科，病历先移除的情况下，PatientEncounter返回为null，病历状态不跟接诊动作进行关联。
            if(patientEncounter != null)
            {
                patientEncounter.addOBActRelWhithOutControlAct(ActRelationshipType.COMP, document);
            }
            
        }
        return this.getResultsDTO("病历移出通过", true, "");
    }
    
    public ResultsDTO medicalRecordRecall(EmrManagerDTO dto) throws Hl7Exception
    {
        Document document = converDocument(dto);
        if (null != document)
        {
            em.merge(document);
        }
        return this.getResultsDTO("病历召回成功", true, "");
    }
    
   
    
    public List<Document> findSubmitEmrPatientByEmpRoleId(String empRoleID) throws Hl7Exception
    {
        StringBuilder jpql = new StringBuilder();
        jpql.append(" select doc from Document doc ");
        jpql.append(" left join doc.prtcptnsActList p ");
        jpql.append(" where doc.codeEtsId='"+ActCode.EMRMANAGER.code().toString()+"'");
        jpql.append(" and  doc.statusCode='1'");
        jpql.append(" and p.typeCode='"+ParticipationType.AUT.code().toString()+"'");
        jpql.append(" and p.roleParticipation.roleId=");
        jpql.append( empRoleID);
        List<Document> list = em.createQuery(jpql.toString()).getResultList();
        return list;
    }


    @SuppressWarnings("unchecked")
    public String findEmrManagerStatueByPatientId(String patientId,String patientNum) throws Hl7Exception
    {
        
        if (StrUtil.isEmpty(patientId) && StrUtil.isEmpty(patientNum))   return null;
        
        StringBuilder jpql = new StringBuilder();
        jpql.append(" select doc.statusCode from Document doc ");
        jpql.append(" left join doc.prtcptnsActList p ");
        jpql.append(" where doc.codeEtsId='"+ActCode.EMRMANAGER.code().toString()+"'");
        jpql.append(" and p.typeCode='"+ParticipationType.RCT.code().toString()+"'");
        jpql.append(" and p.roleParticipation.roleId=");
        jpql.append( patientId);
        jpql.append(" and  p.sequenceNum=");
        jpql.append( patientNum);
        List<String> list = em.createQuery(jpql.toString()).getResultList();
        if (ListUtil.isNotEmpty(list))
        {
            return (String) list.get(0);
        }
        return null;
    }
    
    
    @SuppressWarnings({ "unchecked" })
    public Document findEmrManagerByPatientId(String patientId,String patientNum) throws Hl7Exception
    {
        if (StrUtil.isEmpty(patientId) && StrUtil.isEmpty(patientNum))   return null;
        em.clear();
        StringBuilder jpql = new StringBuilder();
        jpql.append(" select doc from Document doc ");
        jpql.append(" left join doc.prtcptnsActList p ");
        jpql.append( " where doc.codeEtsId='"+ActCode.EMRMANAGER.code().toString()+"'");
        jpql.append( " and p.typeCode='"+ParticipationType.RCT.code().toString()+"'");
        jpql.append(" and p.roleParticipation.roleId=");
        jpql.append( patientId);
        jpql.append(" and  p.sequenceNum=");
        jpql.append( patientNum);
        List<Document> list = em.createQuery(jpql.toString()).getResultList();
        if (ListUtil.isNotEmpty(list))
        {
            return (Document) list.get(0);
        }
        return null;
    }
    
   

    private Document converDocument(EmrManagerDTO dto) throws Hl7Exception
    {
        Document document = findEmrManagerByPatientId(dto.getPatientId(),dto.getPatientNum());
        if(document == null) return null;
        if (StrUtil.isNotEmpty(dto.getRimRoleId()))
        {
            Role returnRole = baseQuery.findRoleById(Long.parseLong(dto.getRimRoleId()));
            ActParticipation participation = new ActParticipation();
            participation.setTypeCode(ParticipationType.AUT);
            if (StrUtil.isNotEmpty(dto.getReason()))
            {
                participation.setNoteText(DataTypeUtil.getED(dto.getReason()));
            }
            document.addParticipation(participation, returnRole);
        }
        // 病历状态修改
        document.setStatusCode(DataTypeUtil.getCS(dto.getCompletionCode()));
        // 最后修改人
        if (StrUtil.isNotEmpty(dto.getLoginBaseInfoDTO().getLastUpdateBy()))
        {
            document.setLastUpdatedBy(Long.parseLong(dto.getLoginBaseInfoDTO().getLastUpdateBy()));
            document.setLastUpdateDate(DateUtil.getTimestamp(DateUtil.GetDateTime()));
        }
        return document;
    }

    private void converDocToDto(Document document, EmrManagerDTO dto) throws Hl7Exception
    {
        // 病历管理状态
        if (StrUtil.isNotEmpty(dto.getCompletionCode()))
        {
            document.setStatusCode(DataTypeUtil.getCS(dto.getCompletionCode()));
        }
        // 病历管理内容（可包含描述，大文本信息等）
        if (StrUtil.isNotEmpty(dto.getReason()))
        {
            document.setText(DataTypeUtil.getED(dto.getReason()));
        }
        // 创建人
        if (StrUtil.isNotBlank(dto.getLoginBaseInfoDTO().getOperateId()))
        {
            document.setCreatedBy(Long.parseLong(dto.getLoginBaseInfoDTO().getOperateId()));
            document.setCreationDate(DateUtil.getTimestamp(DateUtil.GetDateTime()));
        }
        // 最后修改人
        if (StrUtil.isNotBlank(dto.getLoginBaseInfoDTO().getLastUpdateBy()))
        {
            document.setLastUpdatedBy(Long.parseLong(dto.getLoginBaseInfoDTO().getLastUpdateBy()));
            document.setLastUpdateDate(DateUtil.getTimestamp(DateUtil.GetDateTime()));
        }
    }

    private Map<CS,Role> findEmrManegerParticiRole(EmrManagerDTO dto) throws Hl7Exception
    {
        Map<CS,Role> scopeMap = new HashMap<CS,Role>();
        
        // 患者角色
        Role patientRole = baseQuery.findRoleById(Long.parseLong(dto.getPatientId()));
        if (null != patientRole)
        {
            scopeMap.put(ParticipationType.RCT,patientRole);
        }

        // 操作员角色
        Role authRole = baseQuery.findRoleById(Long.parseLong(dto.getRimRoleId()));
        if (null != authRole)
        {
            scopeMap.put(ParticipationType.AUT,authRole);
        }
        
        return scopeMap;
    }
    
    private void constructParticipationList(Map<CS,Role> socopeMap,EmrManagerDTO emr) throws Hl7Exception
    {
        if(!socopeMap.isEmpty())
        {
            Set<CS> set = socopeMap.keySet();
            for(Iterator<CS> it = set.iterator();it.hasNext();)
            {
                CS typeCode = it.next();
                Role partRole = socopeMap.get(typeCode);
                ActParticipation part = getActFactory().newActParticipation();
                part.setTypeCode(typeCode);
                if(typeCode.equals(ParticipationType.RCT))
                {
                    //患者住院次数
                    part.setSequenceNumber(DataTypeUtil.getINT(Long.valueOf(emr.getPatientNum())));
                }
                addParticipation(partRole, part);
            }
        }
    }
    

}
